<template>
  <div class="workflow-canvas">
    <VueFlow
      id="workflow-canvas"
      v-model:nodes="nodes"
      v-model:edges="edges"
      :default-zoom="1"
      :min-zoom="0.2"
      :max-zoom="4"
      :default-edge-options="{ type: 'smoothstep', animated: true }"
      :connection-line-type="'smoothstep'"
      :connection-mode="'loose'"
      :snap-to-grid="true"
      :snap-grid="[15, 15]"
      :is-valid-connection="isValidConnection"
      @drop="onDrop"
      @dragover="onDragOver"
      @node-click="onNodeClick"
      @edge-click="onEdgeClick"
      @pane-click="onPaneClick"
      @connect="onConnect"
      @connect-start="onConnectStart"
      @connect-end="onConnectEnd"
      class="vue-flow-container"
    >
      <Background pattern-color="#aaa" :gap="16" />
      <Controls />
      <MiniMap />

      <!-- 自定义节点 -->
      <template #node-create_experiment="{ data }">
        <CustomNode :data="data" type="create_experiment" />
      </template>
      <template #node-download_data="{ data }">
        <CustomNode :data="data" type="download_data" />
      </template>
      <template #node-data_processing="{ data }">
        <CustomNode :data="data" type="data_processing" />
      </template>
      <template #node-condition_branch="{ data }">
        <CustomNode :data="data" type="condition_branch" />
      </template>
    </VueFlow>
  </div>
</template>

<script setup>
import { ref, watch, onMounted, nextTick } from 'vue'
import { VueFlow, useVueFlow } from '@vue-flow/core'
import { Background } from '@vue-flow/background'
import { Controls } from '@vue-flow/controls'
import { MiniMap } from '@vue-flow/minimap'
import CustomNode from './CustomNode.vue'
import { createNewNode } from './nodeTypes'

const props = defineProps({
  modelValue: {
    type: Object,
    default: () => ({ nodes: [], edges: [] })
  },
  readonly: {
    type: Boolean,
    default: false
  }
})

const emit = defineEmits(['update:modelValue', 'node-selected', 'edge-selected'])

let vueFlowInstance = null

const nodes = ref(props.modelValue.nodes || [])
const edges = ref(props.modelValue.edges || [])

// 监听节点和边的变化，同步到父组件
watch([nodes, edges], () => {
  emit('update:modelValue', {
    nodes: nodes.value,
    edges: edges.value
  })
}, { deep: true })

// 监听父组件的变化
watch(() => props.modelValue, (newVal) => {
  if (newVal) {
    nodes.value = newVal.nodes || []
    edges.value = newVal.edges || []
  }
}, { deep: true })

// 初始化 VueFlow 实例
onMounted(async () => {
  await nextTick()
  vueFlowInstance = useVueFlow('workflow-canvas')
})

// 拖放节点
const onDrop = (event) => {
  event.preventDefault()

  const nodeTypeData = JSON.parse(event.dataTransfer.getData('application/vueflow'))
  if (!nodeTypeData || !vueFlowInstance) return

  const position = vueFlowInstance.screenToFlowCoordinate({
    x: event.clientX,
    y: event.clientY
  })

  const newNode = createNewNode(nodeTypeData.type, position)
  vueFlowInstance.addNodes([newNode])
}

const onDragOver = (event) => {
  event.preventDefault()
  event.dataTransfer.dropEffect = 'move'
}

// 节点点击
const onNodeClick = ({ node }) => {
  emit('node-selected', node)
}

// 边点击
const onEdgeClick = ({ edge }) => {
  emit('edge-selected', edge)
}

// 画布点击
const onPaneClick = () => {
  emit('node-selected', null)
  emit('edge-selected', null)
}

// 连接验证
const isValidConnection = (connection) => {
  // 1. 不能连接自己
  if (connection.source === connection.target) {
    console.warn('不能连接到自己')
    return false
  }

  // 2. 检查是否会形成循环（可选，根据业务需求）
  // 这里暂时允许循环，如果需要禁止循环可以添加检测逻辑

  return true
}

// 连接事件处理
const onConnect = (params) => {
  // 验证连接
  if (!isValidConnection(params)) {
    return
  }

  // 检查是否已存在相同的连接
  const existingEdge = edges.value.find(
    edge => edge.source === params.source && edge.target === params.target
  )
  if (existingEdge) {
    console.warn('连接已存在')
    return
  }

  // 创建新的连接
  const newEdge = {
    id: `edge_${Date.now()}_${Math.random().toString(36).substring(2, 11)}`,
    source: params.source,
    target: params.target,
    sourceHandle: params.sourceHandle,
    targetHandle: params.targetHandle,
    type: 'smoothstep',
    animated: true
  }

  if (vueFlowInstance) {
    vueFlowInstance.addEdges([newEdge])
  }
}

const onConnectStart = (params) => {
  console.log('连接开始:', params)
}

const onConnectEnd = (event) => {
  console.log('连接结束:', event)
}

// 暴露方法给父组件
const deleteNode = (nodeId) => {
  if (vueFlowInstance) {
    vueFlowInstance.removeNodes([nodeId])
  }
}

const deleteEdge = (edgeId) => {
  if (vueFlowInstance) {
    vueFlowInstance.removeEdges([edgeId])
  }
}

const updateNode = (nodeId, data) => {
  const nodeIndex = nodes.value.findIndex(n => n.id === nodeId)
  if (nodeIndex === -1) {
    console.warn('Node not found:', nodeId)
    return
  }

  const node = nodes.value[nodeIndex]

  // 确保 config 是对象类型
  const mergedData = { ...node.data, ...data }
  if (mergedData.config && Array.isArray(mergedData.config)) {
    console.warn('Config is array, converting to empty object')
    mergedData.config = {}
  }

  // 方法1: 直接更新 nodes ref（触发响应式）
  nodes.value[nodeIndex] = {
    ...node,
    data: mergedData
  }

  // 方法2: 同时使用 VueFlow API 确保内部状态同步
  if (vueFlowInstance) {
    // 使用 nextTick 确保响应式更新后再同步 VueFlow
    nextTick(() => {
      vueFlowInstance.updateNode(nodeId, {
        data: mergedData
      })
    })
  }
}

defineExpose({
  deleteNode,
  deleteEdge,
  updateNode
})
</script>

<style lang="scss">
.workflow-canvas {
  width: 100%;
  height: 100%;
  background: #f5f5f5;

  .vue-flow-container {
    height: 100%;
  }

  :deep(.vue-flow__minimap) {
    background: white;
    border: 1px solid #e4e7ed;
  }

  :deep(.vue-flow__controls) {
    button {
      background: white;
      border: 1px solid #e4e7ed;

      &:hover {
        background: #f5f7fa;
      }
    }
  }

  // 连接线样式优化
  :deep(.vue-flow__edge) {
    cursor: pointer;

    .vue-flow__edge-path {
      stroke: #409EFF;
      stroke-width: 2;
      transition: stroke-width 0.2s ease, stroke 0.2s ease;
    }

    &:hover .vue-flow__edge-path {
      stroke: #66B1FF;
      stroke-width: 3;
    }

    &.selected .vue-flow__edge-path {
      stroke: #67C23A;
      stroke-width: 3;
    }

    &.animated .vue-flow__edge-path {
      stroke-dasharray: 5;
      animation: dashdraw 0.5s linear infinite;
    }

    // 连接线文本标签
    .vue-flow__edge-text {
      font-size: 12px;
      fill: #606266;
    }
  }

  // 正在连接的临时连接线
  :deep(.vue-flow__connectionline) {
    .vue-flow__connection-path {
      stroke: #E6A23C;
      stroke-width: 2;
      stroke-dasharray: 5;
      animation: dashdraw 0.5s linear infinite;
    }
  }

  // 连接点样式优化
  :deep(.vue-flow__handle) {
    width: 14px;
    height: 14px;
    border-radius: 50%;
    border: 3px solid #409EFF;
    background: white;
    cursor: crosshair;
    transition: all 0.2s ease;

    &.vue-flow__handle-left {
      left: -7px;
    }

    &.vue-flow__handle-right {
      right: -7px;
    }

    &:hover {
      background: #409EFF;
      transform: scale(1.4);
      box-shadow: 0 0 0 4px rgba(64, 158, 255, 0.2);
      border-width: 3px;
    }

    // 增大可点击区域
    &::before {
      content: '';
      position: absolute;
      top: -8px;
      left: -8px;
      right: -8px;
      bottom: -8px;
      border-radius: 50%;
    }

    // 连接状态
    &.connectable {
      border-color: #67C23A;
    }

    &.connecting {
      background: #E6A23C;
      border-color: #E6A23C;
      animation: pulse 1s infinite;
    }
  }

  @keyframes pulse {
    0%, 100% {
      box-shadow: 0 0 0 0 rgba(230, 162, 60, 0.7);
    }
    50% {
      box-shadow: 0 0 0 8px rgba(230, 162, 60, 0);
    }
  }

  @keyframes dashdraw {
    from {
      stroke-dashoffset: 10;
    }
    to {
      stroke-dashoffset: 0;
    }
  }
}
</style>
